package com.eralink.unionuhfreader.ui;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eralink.uhfreaderlib.EraLinkUHFReaderCmdCode;
import com.eralink.uhfreaderlib.EraLinkUHFReaderInterface;
import com.eralink.uhfreaderlib.EraLinkUHFReaderReportCallback;
import com.eralink.unionuhfreader.MainActivity;
import com.eralink.unionuhfreader.MyApplication;
import com.eralink.unionuhfreader.R;
import com.eralink.unionuhfreader.adapter.ManualCateRecycleViewAdapter;
import com.eralink.unionuhfreader.adapter.ProductRecycleViewAdapter;
import com.eralink.unionuhfreader.base.BaseActivity;
import com.eralink.unionuhfreader.bean.CateProduct;
import com.eralink.unionuhfreader.bean.EPCBean;
import com.eralink.unionuhfreader.bean.FormOrder;
import com.eralink.unionuhfreader.bean.Product;
import com.eralink.unionuhfreader.bean.ProductOrderDo;
import com.eralink.unionuhfreader.bean.ProductVo;
import com.eralink.unionuhfreader.bean.ReaderBean;
import com.eralink.unionuhfreader.bean.RetailProductPageReqVO;
import com.eralink.unionuhfreader.dialog.CommonDialog;
import com.eralink.unionuhfreader.http.Api;
import com.eralink.unionuhfreader.http.JsonCallBack;
import com.eralink.unionuhfreader.http.Result;
import com.eralink.unionuhfreader.util.CacheNode;
import com.eralink.unionuhfreader.util.CachePool;
import com.eralink.unionuhfreader.util.Canstant;
import com.eralink.unionuhfreader.util.EPCReportDataParseUtil;
import com.eralink.unionuhfreader.util.EralinkApiErrDefinition;
import com.eralink.unionuhfreader.util.ErrString;
import com.eralink.unionuhfreader.util.SharedPreferencesUtil;
import com.eralink.unionuhfreader.util.StringUtils;
import com.eralink.unionuhfreader.util.Utils;
import com.lxj.xpopup.XPopup;
import com.lxj.xpopup.core.BasePopupView;
import com.lzy.okgo.model.Response;

import java.lang.ref.WeakReference;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicInteger;

public class ReadActivity extends BaseActivity implements EraLinkUHFReaderReportCallback, ManualCateRecycleViewAdapter.CalCount {
    private EraLinkUHFReaderInterface uhfReaderInterface;
    private ProductRecycleViewAdapter mAdapter;//购物车适配器
    private LinearLayoutManager mLinearLayoutManager;//布局管理器
    private RecyclerView rc_list;
    private TextView tv_count, username;
    private byte reader_id = 0;
    private List<ProductVo> productDatas = new ArrayList<>();

    private Button btn_cancel_js, btn_reback, btn_going, btn_next;

    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_read);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        rc_list = findViewById(R.id.rc_list);
        tv_count = findViewById(R.id.tv_count);
        username = findViewById(R.id.username);
        if (MyApplication.memberUserInfoRespVO != null) {
            username.setText("会员：" + MyApplication.memberUserInfoRespVO.getMobile());
        }
        mAdapter = new ProductRecycleViewAdapter(this, productDatas);
        mAdapter.setCalCount(this);
        mLinearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        rc_list.setLayoutManager(mLinearLayoutManager);
        rc_list.setAdapter(mAdapter);
        btn_cancel_js = findViewById(R.id.btn_cancel_js);
        connectReaderAction();
        btn_cancel_js.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                canceljs();
            }
        });
        btn_reback = findViewById(R.id.btn_reback);
        btn_reback.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                canceljs();
                finish();
            }
        });
        btn_going = findViewById(R.id.btn_going);
        btn_going.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                inventoryOnceAction();
            }
        });
        btn_next = findViewById(R.id.btn_next);
        btn_next.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showrefundDialog();
            }
        });
        timehandle.postDelayed(runnable, 1000 * 3);
      //  addEpc("123");
      //  addEpc("321");
    }

    Handler timehandle = new Handler();
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            inventoryOnceAction();
            timehandle.postDelayed(runnable, 1000 * 3);
        }
    };
    CommonDialog cashRefundDialog;

    private void showrefundDialog() {
        cashRefundDialog = new CommonDialog(this, "请确认商品件数", "当前" + productDatas.size() + "件，商品一经售出，不在退回").setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (v.getId()) {
                    case R.id.tv_cancel:

                        break;
                    case R.id.tv_confirm:
                        gotocreateorder();

                        break;
                }

                //SystemUIUtils.setStickFullScreen(MainActivity.this.getWindow().getDecorView());
                cashRefundDialog.dismiss();
            }
        });
        cashRefundDialog.show();
    }

    private void gotocreateorder() {
        FormOrder formOrder = new FormOrder();
        if (MyApplication.memberUserInfoRespVO != null) {
            formOrder.setUserMobile(MyApplication.memberUserInfoRespVO.getMobile());
        }
        formOrder.setClientId(MyApplication.getSn());
        formOrder.setClientType("APP");
        formOrder.setStoreId(MyApplication.cashierDO.getStoreId());
        List<Product> products=new ArrayList<>();
        for (ProductVo productData : productDatas) {
            Product product = new Product();
            product.setProductId(productData.getProductId());
            product.setCount(productData.getCount());
            product.setDerate(0);
            product.setDiscount(0);
            products.add(product);
        }
        formOrder.setProducts(products);
        MyApplication.getInstance().cancelPaydata();
        Api.createOrder(formOrder, new JsonCallBack<Result<ProductOrderDo>>() {
            @Override
            public void onSuccess(Response<Result<ProductOrderDo>> response) {
                Result<ProductOrderDo> productOrderDoResult = response.body();
                if (productOrderDoResult != null && productOrderDoResult.isSucess()) {
                    Bundle bundle = new Bundle();
                    bundle.putString("products", JSON.toJSONString(productDatas));
                    bundle.putSerializable("productorder", productOrderDoResult.getData());
                    Intent intent = new Intent(ReadActivity.this, ScanPayActivity.class);
                    intent.putExtra("p", bundle);
                    startActivity(intent);
                    finish();
                } else {
                    showToast(productOrderDoResult.getMsg());
                }
            }
        });
    }

    private void canceljs() {
        productDatas.clear();//清空列表数据集
        tv_count.setText("合计:0");
        mAdapter.notifyDataSetChanged();
    }

    @Override
    protected void onDestroy() {
        if (uhfReaderInterface != null) {
            uhfReaderInterface.close();
            uhfReaderInterface = null;
        }
        super.onDestroy();

    }

    private void connectReaderAction() {
        if (!checkOpenRfid()){
            return;
        }
        if (uhfReaderInterface != null) {
            return;
        }
        String connectStr = String.format(Locale.getDefault(), "CommType=COM;ComPath=%s;Address=1;Baud=%d;Databits=8;Stopbits=1;Parity=0", "/dev/ttyS1", 115200);
        uhfReaderInterface = new EraLinkUHFReaderInterface();
        final int result = uhfReaderInterface.connect(connectStr, this);
        if (EralinkApiErrDefinition.ErrNoError != result) {
            uhfReaderInterface = null;
            Toast.makeText(this, getResources().getString(ErrString.getErrId(result)), Toast.LENGTH_SHORT).show();
            return;
        }
        Toast.makeText(this, "设备链接成功", Toast.LENGTH_SHORT).show();
        //setControlStatusOnReaderConnectStatus(true);
        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    private boolean checkOpenRfid(){
        int i= (int) SharedPreferencesUtil.getData(this, Canstant.RFID_SWITCH_KEY,0);
        if (i==0){
            return false;
        }
        return true;
    }
    private void inventoryOnceAction() {
        if (!checkOpenRfid()){
            return;
        }
        if (!checkOpenRfid()){
            return;
        }
        if (uhfReaderInterface != null) {
            final int result = uhfReaderInterface.inventoryOnce(reader_id);
            Toast.makeText(this, getResources().getString(ErrString.getErrId(result)), Toast.LENGTH_SHORT).show();
        } else {
           // Log.i(ReadActivity.class.getSimpleName(), "读卡器未连接");
            // Toast.makeText(this, getResources().getString(R.string.connect_reader), Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void report(byte reader_id, int report_cmd_code, byte[] report_data, int report_data_len) {
        String message = String.format("[%s] reader_id: %s, report_cmd_code: %s, report_data: %s, report_data_len: %s.\n",
                Utils.getCurrentTime(), reader_id, report_cmd_code, StringUtils.bytesToHexString(report_data, 0, report_data_len), report_data_len);
        Log.d("ykj520", message);

        if (report_cmd_code == EraLinkUHFReaderCmdCode.CmdInventoryOnce || report_cmd_code == EraLinkUHFReaderCmdCode.CmdStartInventory) {
            //对盘点一次，report_cmd_code=37；对连续盘点，report_cmd_code=42
            reportForInventory(reader_id, report_data, report_data_len);
        } else if (report_cmd_code == EraLinkUHFReaderCmdCode.CmdStartMultiBankAutoRead) {
            //2.2.11.	多区域自动读卡上报
            reportForMultiBankAutoRead(reader_id, report_data, report_data_len);
        } else if (report_cmd_code == EraLinkUHFReaderCmdCode.CmdStartAutoRead) {
            //2.2.8.	自动读卡上报
            reportForAutoRead(reader_id, report_data, report_data_len);
        } else if (report_cmd_code == EraLinkUHFReaderCmdCode.CmdDeviceInfoReport) {
            //2.2.5.	读写器连接上报 在读写器作为Tcp Client时，会上报设备IP、序列号信息和设备名称，这时，report_cmd_code=103，
            reportReaderConnect(reader_id, report_data, report_data_len);
        } else if (report_cmd_code == EraLinkUHFReaderCmdCode.CmdReaderCommunicationBreak) {
            //如果读写器断开，则report_cmd_code=255，report_data_len=0
            reportReaderDisconnect(reader_id);
        } else {
            reportForOthers(reader_id, message);
        }
    }

    private final AtomicInteger tagReportTotalNumber = new AtomicInteger(0);
    private final AtomicInteger statisticsIntervalTagNumber = new AtomicInteger(0);
    private static final int cmd_update_epc = 0x01;
    private static final int cmd_update_inventory_statistic = 0x02;
    private static final int cmd_report_io_failed = 0x03;
    private static final int cmd_auto_read_update = 0x04;
    private static final int cmd_update_auto_read_statistic = 0x05;
    private static final int cmd_multi_bank_auto_read_update = 0x06;
    private static final int cmd_reader_connect = 0x07;
    private static final int cmd_reader_disconnect = 0x08;
    private static final int cmd_others_report = 0xFF;
    private final Handler epcReportHandler = new EPCReportHandler(this);
    private int reader_work_role = -1; // 0, server; 1, client
    private final Hashtable<String, EPCBean> epcBeanMap = new Hashtable<>();

    private void reportForInventory(byte reader_id, final byte[] report_data, int report_data_len) {
        if (9 > report_data_len) {
            return;
        }

        tagReportTotalNumber.incrementAndGet();
        statisticsIntervalTagNumber.incrementAndGet();

        CacheNode cacheNode = CachePool.getInstance().obtain(1 + report_data_len);
        cacheNode.getBuffer()[0] = reader_id;
        System.arraycopy(report_data, 0, cacheNode.getBuffer(), 1, report_data_len);
        cacheNode.setBufferSize(1 + report_data_len);

        Message message = new Message();
        message.what = cmd_update_epc;
        message.obj = cacheNode;
        epcReportHandler.sendMessage(message);
    }

    private void reportForAutoRead(byte reader_id, final byte[] report_data, int report_data_len) {
        if (1 >= report_data_len) {
            return;
        }
        CacheNode cacheNode = CachePool.getInstance().obtain(1 + report_data_len);
        cacheNode.getBuffer()[0] = reader_id;
        System.arraycopy(report_data, 0, cacheNode.getBuffer(), 1, report_data_len);
        cacheNode.setBufferSize(1 + report_data_len);

        Message message = new Message();
        message.what = cmd_auto_read_update;
        message.obj = cacheNode;
        epcReportHandler.sendMessage(message);
    }

    private void reportForMultiBankAutoRead(byte reader_id, final byte[] report_data, int report_data_len) {
        if (1 >= report_data_len) {
            return;
        }

        CacheNode cacheNode = CachePool.getInstance().obtain(1 + report_data_len);
        cacheNode.getBuffer()[0] = reader_id;
        System.arraycopy(report_data, 0, cacheNode.getBuffer(), 1, report_data_len);
        cacheNode.setBufferSize(1 + report_data_len);

        Message message = new Message();
        message.what = cmd_multi_bank_auto_read_update;
        message.obj = cacheNode;
        epcReportHandler.sendMessage(message);
    }

    private void reportReaderConnect(byte reader_id, final byte[] report_data, int report_data_len) {
        if (reader_work_role == 0) {
            return;
        }
        final String device_info = new String(report_data, 0, report_data_len);
        final String[] fields = device_info.split(",");
        ReaderBean readerBean = new ReaderBean();
        readerBean.setReaderId(reader_id);
        if (fields.length == 2) {
            readerBean.setSn(fields[0]);
            readerBean.setName(fields[1]);
        } else { // fields.length == 3
            readerBean.setIp(fields[0]);
            readerBean.setSn(fields[1]);
            readerBean.setName(fields[2]);
        }

        Message message = new Message();
        message.what = cmd_reader_connect;
        message.obj = readerBean;
        epcReportHandler.sendMessage(message);
    }

    private void reportReaderDisconnect(byte reader_id) {
        Message message = new Message();
        message.what = cmd_reader_disconnect;
        message.obj = reader_id;
        epcReportHandler.sendMessage(message);
    }

    private void reportForOthers(byte reader_id, String report) {
        Message message = new Message();
        message.what = cmd_others_report;
        message.obj = report;
        epcReportHandler.sendMessage(message);
    }

    /*操作购物车*/
    @Override
    public void addOrDivClick(int postion, int changecount) {
        if (changecount==0){
            productDatas.remove(postion);
        }else {
            productDatas.get(postion).setCount(productDatas.get(postion).getCount()+changecount);
        }
        //显示
        mAdapter.notifyDataSetChanged();
        calPrice();
    }

    private static class EPCReportHandler extends Handler {
        private final WeakReference<ReadActivity> mainActivityWeakReference;

        public EPCReportHandler(ReadActivity mainActivity) {
            mainActivityWeakReference = new WeakReference<>(mainActivity);
        }

        public void handleMessage(Message msg) {
            switch (msg.what) {
                case cmd_report_io_failed:
                    //processIOFailed((Integer) msg.obj);
                    break;
                case cmd_update_epc:
                    updateInventory(msg);
                    break;
                case cmd_update_inventory_statistic:
                    //updateStatistics();
                    break;
                case cmd_multi_bank_auto_read_update:
                    //updateMultiBankAutoRead(msg);
                    break;
                case cmd_auto_read_update:
                    //updateAutoRead(msg);
                    break;
                case cmd_update_auto_read_statistic:
                    //updateAutoReadStatistics();
                    break;
                case cmd_reader_connect:
                    processReaderConnect(msg);
                    break;
                case cmd_reader_disconnect:
                    //processReaderDisconnect(msg);
                    break;
                case cmd_others_report:
                    //othersReport(msg);
                default:
                    break;
            }
        }

        private void updateInventory(Message msg) {
            ReadActivity mainActivity = mainActivityWeakReference.get();
            if (mainActivity == null) {
                return;
            }
            CacheNode cacheNode = (CacheNode) msg.obj;
            final EPCBean epcBean = new EPCBean();
            EPCReportDataParseUtil.parseInventoryEPCReport(cacheNode, epcBean);
            CachePool.getInstance().release(cacheNode);

            EPCBean oldEpcBean = mainActivity.epcBeanMap.get(epcBean.getKey());
            if (oldEpcBean != null) {
                oldEpcBean.setRssi(epcBean.getRssi());
                oldEpcBean.setAnt(epcBean.getAnt());
                oldEpcBean.setCount(oldEpcBean.getCount() + 1);
            } else {

                epcBean.setCount(1);
                mainActivity.addEpc(epcBean.getEPC());
                mainActivity.epcBeanMap.put(epcBean.getKey(), epcBean);
            }
        }

        private void processReaderConnect(Message msg) {
            ReadActivity readActivity = mainActivityWeakReference.get();
            if (readActivity == null) {
                return;
            }
            ReaderBean readerBean = (ReaderBean) msg.obj;
            readActivity.reader_id = readerBean.getReaderId();
        }
    }

    private void addEpc(String epc) {
        Log.d("读到EPC", epc);
        RetailProductPageReqVO vo=new RetailProductPageReqVO();
        vo.setEpc(epc);
        Api.getProduct(vo, new JsonCallBack<Result<String>>() {
            @Override
            public void onSuccess(Response<Result<String>> response) {
                Result<String> result = response.body();
                System.out.println(result.getData());
                if (result.getData() != null) {
                    JSONObject jsonObject = JSON.parseObject(result.getData());
                    int total = jsonObject.getIntValue("total");
                    if (total > 0) {
                        List<ProductVo> productVos = JSON.parseArray(jsonObject.getString("list"), ProductVo.class);
                        for (ProductVo productVo : productVos) {
                            boolean already=false;
                            for (ProductVo productData : productDatas) {
                                if (productData.getProductId().equals(productVo.getProductId())){
                                    already=true;
                                    break;
                                }
                            }
                            if (!already){
                                productVo.setCount(1);
                                productDatas.add(productVo);
                            }
                        }
                        mAdapter.notifyDataSetChanged();
                        calPrice();
                    }
                }
            }
        });
    }

    private void calPrice() {
        BigDecimal total = BigDecimal.ZERO;
        for (ProductVo productData : productDatas) {
            BigDecimal price = new BigDecimal(productData.getSalePrice()).multiply(new BigDecimal(productData.getCount()));
            total = total.add(price);
        }
        tv_count.setText("总计：" + total.toString());
    }

    /*扫码枪*/
    private Handler myHandler = new Handler();
    int oldLen = 0;
    int len = 0;
    boolean isScaning = false;
    private StringBuilder sb = new StringBuilder();
    private void startScan() {
        Log.d(">>扫码>>>", ">>>>>");
        if (isScaning) {
            return;
        }
        isScaning = true;
        timerScanCal();
    }

    private void timerScanCal() {
        oldLen = len;
        myHandler.postDelayed(scan, 100);
    }

    Runnable scan = new Runnable() {
        @Override
        public void run() {
            if (oldLen != len) {
                timerScanCal();
                return;
            }
            isScaning = false;
            if (sb.length() > 0) {
                excCode(sb.toString());
                sb.setLength(0);
            } else {
                Log.d(">>扫码>>>", ">>sb>>>");
            }
        }

    };

    private void excCode(String code) {
        code = code.replaceAll("[^0-9a-zA-Z]", "");
        Log.e(ReadActivity.class.getSimpleName(), "扫码===" + code);
        if (code.length()>20){
            addEpc(code);
        }else{
            getproductAndAddCate(code);
        }
    }
    private void getproductAndAddCate(String code) {
        RetailProductPageReqVO vo=new RetailProductPageReqVO();
        vo.setBarCode(code);
        BasePopupView popupView = new XPopup.Builder(this)
                .asLoading("正在查询商品....")
                .show();
        Api.getProduct(vo, new JsonCallBack<Result<String>>() {
            @Override
            public void onSuccess(Response<Result<String>> response) {
                popupView.dismiss();
                Result<String> result = response.body();
                System.out.println(result.getData());
                if (result.getData() != null) {
                    JSONObject jsonObject = JSON.parseObject(result.getData());
                    int total = jsonObject.getIntValue("total");
                    if (total > 0) {
                        List<ProductVo> productVos = JSON.parseArray(jsonObject.getString("list"), ProductVo.class);
                        for (ProductVo productVo : productVos) {
                            boolean already=false;
                            for (ProductVo productData : productDatas) {
                                if (productData.getProductId().equals(productVo.getProductId())){
                                    already=true;
                                    productData.setCount(productData.getCount()+1);
                                    break;
                                }
                            }
                            if (!already){
                                productVo.setCount(1);
                                productDatas.add(productVo);
                            }
                        }
                        mAdapter.notifyDataSetChanged();
                        calPrice();
                    }else {
                        showToast("该门店没有对应的商品");
                    }
                }
            }

            @Override
            public void onError(Response<Result<String>> response) {
                super.onError(response);
                popupView.dismiss();
            }
        });
    }
    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        int action = event.getAction();
        switch (action) {
            case KeyEvent.ACTION_DOWN:

                if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP) {
                    return super.dispatchKeyEvent(event);
                }
                if (event.getKeyCode() == KeyEvent.KEYCODE_DEL) {
                    return super.dispatchKeyEvent(event);
                }
                if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN) {
                    return super.dispatchKeyEvent(event);
                }
                if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
                    return super.dispatchKeyEvent(event);
                }
                if (event.getKeyCode() == KeyEvent.KEYCODE_MENU) {
                    return super.dispatchKeyEvent(event);
                }
                if (event.getKeyCode() == KeyEvent.KEYCODE_HOME) {
                    return super.dispatchKeyEvent(event);
                }
                if (event.getKeyCode() == KeyEvent.KEYCODE_POWER) {
                    return super.dispatchKeyEvent(event);
                }
                int unicodeChar = event.getUnicodeChar();
                sb.append((char) unicodeChar);
                Log.e("MainActivity", "dispatchKeyEvent: " + unicodeChar + " " + event.getKeyCode() + " scancode=" + event.getScanCode());
                len++;
                startScan();
                return true;
            default:
                break;
        }
        return super.dispatchKeyEvent(event);
    }

}
